#include "protreethread.h"
#include <QDir>
#include <QFileInfoList>
#include "protreeitem.h"
#include "const.h"
#include <QDebug>

ProTreeThread::ProTreeThread(const QString &src_path, const QString &dist_path,
    QTreeWidgetItem *parent_item, int& file_count, QTreeWidget *self, QTreeWidgetItem *root, QObject *parent)
    : QThread(parent), _src_path(src_path), _dist_path(dist_path), _parent_item(parent_item), _self(self), _root(root), _bstop(false)
{}


ProTreeThread::~ProTreeThread() {}

// ProTreeThread 线程的业务处理
void ProTreeThread::run()
{
    qDebug() << "ProTreeThread::run" << Qt::endl;
    CreateProTree(_src_path, _dist_path, _parent_item, _file_count, _self, _root); // preItem 默认为 nullptr
    if(_bstop == true){
        auto path = dynamic_cast<ProTreeItem*>(_root)->GetPath();
        auto index = _self->indexOfTopLevelItem(_root);
        delete _self->takeTopLevelItem(index);
        QDir dir(path);
        dir.removeRecursively();

        return;
    }

    // 上面调用的 CreateProTree 函数，直接把 QFileInfoList list 全部给遍历完了 ---> 全部加载完了
    emit SigFinishProgress(_file_count);
}

// 创建目录树
// 是一个递归的函数: 因为传递进来的 path(文件夹) 里面可能还会有文件夹，所以得递归进去遍历的哦【所以下面也是得及时控制线程的退出问题】
void ProTreeThread::CreateProTree(const QString &src_path, const QString &dist_path,
    QTreeWidgetItem *parent_item, int &file_count, QTreeWidget *self, QTreeWidgetItem *root, QTreeWidgetItem *preItem)
{
    qDebug() << "ProTreeThread::CreateProTree" << Qt::endl;
    if(_bstop == true){
        return;
    }

    // src_path 和 dist_path 不同的话是需要拷贝的
    bool needCopy = true;
    if(src_path == dist_path){
        needCopy = false;
    }

    QDir import_dir(src_path);
    qDebug() << "src_path: " << src_path << "  dist_path: " << dist_path << Qt::endl;
    QStringList nameFilters;
    import_dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); // 文件夹  文件  当前目录.和上级目录..: 除了目录或文件，其他的过滤掉
    import_dir.setSorting(QDir::Name); // 按照名字来排序
    QFileInfoList list = import_dir.entryInfoList();
    for(int i = 0; i < list.size(); i++){
        if(_bstop == true) return; // 及时退出

        QFileInfo fileInfo = list.at(i);
        bool IsDir = fileInfo.isDir();
        if(IsDir == true){ // 是目录的情况
            if(_bstop == true) return;

            file_count++;
            emit SigUpdateProgress(file_count);

            QDir dist_dir(dist_path);
            QString sub_dist_path = dist_dir.absoluteFilePath(fileInfo.fileName());
            QDir sub_dist_dir(sub_dist_path);
            if(sub_dist_dir.exists() == false){
                bool ok = sub_dist_dir.mkpath(sub_dist_path);
                if(ok == false){
                    continue;
                }
            }

            auto* item = new ProTreeItem(parent_item, fileInfo.fileName(), sub_dist_path, root, TreeItemDir);
            item->setData(0, Qt::DisplayRole, fileInfo.fileName());
            item->setData(0, Qt::DecorationRole, QIcon(":/icon/dir.png"));
            item->setData(0, Qt::ToolTipRole, sub_dist_path);

            CreateProTree(fileInfo.absoluteFilePath(), sub_dist_path, item, file_count, self, root, preItem); // 递归调用
        }else{ // 不是目录的情况
            if(_bstop == true) return;

            const QString& suffix = fileInfo.completeSuffix();
            if(suffix != "png" && suffix != "jpeg" && suffix != "jpg"){
                qDebug() << "suffix is not pic " << suffix << Qt::endl;
                continue;
            }
            file_count++; // 是一个图片文件 ---> file_count++ ---> 通知外面的导入图片进度的界面
            emit SigUpdateProgress(file_count);
            if(needCopy == false){
                continue;
            }

            // 需要拷贝的情况
            QDir dist_dir(dist_path);
            QString dist_file_path = dist_dir.absoluteFilePath(fileInfo.fileName());
            if(QFile::copy(fileInfo.absoluteFilePath(), dist_file_path) == false){
                continue;
            }
            auto* item = new ProTreeItem(parent_item, fileInfo.fileName(), dist_file_path, root, TreeItemPic); // 创建一个新的节点 new_item
            item->setData(0, Qt::DisplayRole, fileInfo.fileName());
            item->setData(0, Qt::DecorationRole, QIcon(":/icon/pic.png"));
            item->setData(0, Qt::ToolTipRole, dist_file_path);


            // 如果前一个节点不为空的话，那么就相当于是一条链表了，得串连起来
            // 是一条双向链表
            if(preItem != nullptr){
                auto* pre_proitem = dynamic_cast<ProTreeItem*>(preItem);
                pre_proitem->SetNextItem(item);
            }
            item->SetProItem(preItem);
            preItem = item;
        }
    }
}

// 接收 ProTreeWidget::SigCancelProgress 的信号，触发的槽函数
void ProTreeThread::SlotCancelProgress()
{
    this->_bstop = true;
}
